﻿//  Author:
//       Daniel Großer <olav.daniel.grosser@googlemail.com>
//  
//  Copyright (c) 2012 Copyright (C) 2012 by Daniel Großer. This Code is under GNU LGPL 3.0
// 
//  This program is free software: you can redistribute it and/or modify
//  it under the terms of the GNU Lesser General Public License as published by
//  the Free Software Foundation, either version 3 of the License, or
//  (at your option) any later version.
// 
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU Lesser General Public License for more details.
// 
//  You should have received a copy of the GNU Lesser General Public License
//  along with this program.  If not, see <http://www.gnu.org/licenses/>.

using System;
using System.Collections.Generic;
using System.Linq;

using Beauty;
using Beauty.Tools;
using System.ComponentModel;

namespace Beauty.Test.Languages.Language1
{
    #region Testing Terminals
    public class KeywordNode : ASTNode
    {
        [Keyword("keyword")]
        public object Keyword { get; set; }
    }

    public class DelimeterNode : ASTNode
    {
        [Delimeter(".")]
        public object Delimeter { get; set; }
    }

    public class RegexNode : ASTNode
    {
        [RegExTerminal(@"\d+")]
        public object Number { get; set; }
    }

    public struct CustomDataType
    {
        public CustomDataType(string data)
        {
            Data = data;
        }

        public string Data;
    }

    public class DifferentTerminals : ASTNode
    {
        [Keyword("keyword")]
        public string Keyword_Ignored { get; set; }

        [Keyword("keyword", Ignore = false)]
        public string Keyword_NotIgnored { get; set; }

        [Keyword("keyword", Ignore = false, Comparison = StringComparison.InvariantCultureIgnoreCase)]
        public string Keyword_NotIgnoredCaseSensitive { get; set; }

        [Keyword("keyword", Ignore = false)]
        public CustomDataType Keyword_CustomData { get; set; }

        [Keyword("keyword", Ignore = false)]
        public Token Keyword_PredefinedData { get; set; }

        [RegExTerminal(@"\d+")]
        public int RegEx_IConvertible { get; set; }

        [Keyword("keyword")]
        public string KeywordFollowedByNonSpace { get; set; }
        [Delimeter(".")]
        public char Qualifier { get; set; }
        [RegExTerminal("identifier")]
        public string Identifier2 { get; set; }
    }
    #endregion

    #region Testing Optionals
    public abstract class BeginOrEnd : ASTNode { }
    public class Declaration : ASTNode { [Keyword("declare")]    public string Declare { get; set; } }
    public class BeginKeyword : BeginOrEnd { [Keyword("begin")]    public string Keyword { get; set; } }
    public class EndKeyword : BeginOrEnd { [Keyword("end")]    public string Keyword { get; set; } }
    public class Block : ASTNode { [Production(IsOptional = true)]    public Declaration Variables { get; set; } [Production]    public BeginKeyword Begin { get; set; } [Production]    public EndKeyword End { get; set; } }
    #endregion

    #region Testing Repetitions
    public class Sets : ASTNode
    {
        public Sets()
        {
            Numbers5.Add(new RegexNode() { Parent = this, Number = 123 });
        }

        [Delimeter("{")]
        public char Open1a { get; set; }
        [Production]
        public RegexNode[] Numbers1a { get; set; }
        [Delimeter("}")]
        public char Close1a { get; set; }

        [Delimeter("[{")]
        public char Open1b { get; set; }
        [Production(IsOptional=true)]
        public RegexNode[] Numbers1b { get; set; }
        [Delimeter("}]")]
        public char Close1b { get; set; }

        [Delimeter("{")]
        public char Open2 { get; set; }
        [Production]
        public IEnumerable<RegexNode> Numbers2 { get; set; }
        [Delimeter("}")]
        public char Close2 { get; set; }

        [Delimeter("{")]
        public char Open3 { get; set; }
        [Production]
        public List<RegexNode> Numbers3 { get; set; }
        [Delimeter("}")]
        public char Close3 { get; set; }

        [Delimeter("{")]
        public char Open4 { get; set; }
        [Production]
        public BindingList<RegexNode> Numbers4 { get; set; }
        [Delimeter("}")]
        public char Close4 { get; set; }


        [Delimeter("{")]
        public char Open5 { get; set; }
        private readonly BindingList<RegexNode> m_Numbers5 = new BindingList<RegexNode>();
        [Production]
        public BindingList<RegexNode> Numbers5 { get { return m_Numbers5; } }
        [Delimeter("}")]
        public char Close5 { get; set; }
    }

    #endregion

    #region Testing Alternations
    public class Alternation : ASTNode
    {
        [Production]
        public BeginOrEnd FirstEntity { get; set; }

        [Delimeter(".")]
        public object Dot { get; set; }
    }
    #endregion
}
